package hxy.dragon.ktor

import hxy.dragon.ktor.model.Colleagues
import hxy.dragon.ktor.plugins.configureHTTP
import hxy.dragon.ktor.plugins.configureSerialization
import hxy.dragon.ktor.repository.GroupRepository
import hxy.dragon.ktor.repository.GroupRepositoryImpl
import hxy.dragon.ktor.router.configureColleagueRouter
import hxy.dragon.ktor.router.configureGroupRouter
import hxy.dragon.ktor.router.configureIndexRouting
import hxy.dragon.ktor.router.configureUserRouter
import hxy.dragon.ktor.service.GroupService
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.plugins.cors.routing.CORS
import org.jetbrains.exposed.v1.jdbc.Database
import org.jetbrains.exposed.v1.jdbc.SchemaUtils
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
import org.koin.dsl.module
import org.koin.ktor.plugin.Koin
import org.koin.logger.slf4jLogger

fun main(args: Array<String>) {
    val appModule = module {

        // Koin的依赖注入，单例
        single<GroupRepository> { GroupRepositoryImpl() }
        single { GroupService(get()) }
    }

    if (false) {
        io.ktor.server.netty.EngineMain.main(args)
    } else {
        embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
//          https://ktor.io/docs/server-plugins.html
            install(Koin) {
//                slf4jLogger() // 第二种日志引用方式
                modules(appModule)
            }
            install(CORS)
            module()
        }.start(wait = true)
    }
}

// yaml文件里配置了这个模块，所以靠配置文件加载的
fun Application.module() {

    val database = Database.connect(
        url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
        user = "root",
        driver = "org.h2.Driver",
        password = ""
    )

    transaction(database) {
//        SchemaUtils.create(Colleagues)
        SchemaUtils.createMissingTablesAndColumns(Colleagues)
    }

    configureSerialization()
    configureUserRouter(database)
    configureColleagueRouter()
    configureIndexRouting()
    configureGroupRouter()
//    configureMonitoring()
    configureHTTP()
}
